home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-03 | 18.2 KB | 564 lines | [TEXT/MPS ] |
- //----------------------------------------------------------------------------------------
- // UTearOffMenu.cp
- // Copyright © 1988-96 by Apple Computer, Inc. All rights reserved.
- //----------------------------------------------------------------------------------------
-
- #ifndef __UTEAROFFMENUVIEW__
- #include "UTearOffMenuView.h"
- #endif
-
- // MacApp
-
- // #ifndef __UAPPLICATION__
- // #include "UApplication.h"
- // #endif
-
- #if qContainer
- #ifndef __UCONTAINER__
- #include "UContainer.h"
- #endif
- #endif
-
- #ifndef __UDISPATCHER__
- #include "UDispatcher.h"
- #endif
-
- #ifndef __UFAILURE__
- #include "UFailure.h"
- #endif
-
- #ifndef __UGEOMETRY__
- #include "UGeometry.h"
- #endif
-
- #ifndef __UMACAPPGLOBALS__
- #include "UMacAppGlobals.h"
- #endif
-
- #ifndef __UMACAPPUTILITIES__
- #include "UMacAppUtilities.h"
- #endif
-
- #ifndef __UPATCH__
- #include "UPatch.h"
- #endif
-
- #ifndef __UWINDOW__
- #include "UWindow.h"
- #endif
-
- // Toolbox
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __LOWMEM__
- #include <LowMem.h>
- #endif
-
- #ifndef __TEXTEDIT__
- #include <TextEdit.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- // CALib
-
- #if qContainer
- #ifndef _CALIB_
- #include "CALib.h"
- #endif
- #endif
-
- //========================================================================================
- // CLASS TShowTearOffWindowCommand
- //========================================================================================
- #undef Inherited
- #define Inherited TCommand
-
- #pragma segment TearOffDoCommand
- MA_DEFINE_CLASS_M1(TShowTearOffWindowCommand, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TShowTearOffWindowCommand constructor
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffDoCommand
-
- TShowTearOffWindowCommand::TShowTearOffWindowCommand()
- {
- fTearOffWindow = NULL;
- fWhere = gZeroPt;
- } // TShowTearOffWindowCommand::TShowTearOffWindowCommand
-
- //----------------------------------------------------------------------------------------
- // TShowTearOffWindowCommand destructor
- //----------------------------------------------------------------------------------------
- #pragma segment MADestructorRes
-
- TShowTearOffWindowCommand::~TShowTearOffWindowCommand()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // TShowTearOffWindowCommand::IShowTearOffWindowCommand:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffDoCommand
-
- void TShowTearOffWindowCommand::IShowTearOffWindowCommand(TWindow* tearOffWindow,
- CPoint where)
- {
- this->ICommand(cNoCommand, NULL, kCantUndo, kDoesNotCauseChange, NULL);
- fTearOffWindow = tearOffWindow;
- fWhere = where;
- } // TShowTearOffWindowCommand::IShowTearOffWindowCommand
-
- //----------------------------------------------------------------------------------------
- // TShowTearOffWindowCommand::DoIt:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffDoCommand
-
- void TShowTearOffWindowCommand::DoIt() // override
- {
- if (fTearOffWindow)
- {
- fTearOffWindow->Show(FALSE, FALSE); // Hide the window so that Open will call
- fTearOffWindow->fMustForceOnScreen = TRUE; // ForceOnScreen before showing
- fTearOffWindow->fForcedOnScreen = FALSE;
-
- fTearOffWindow->Locate(fWhere, kDontInvalidate);
-
- #if qContainer
- // ••• MDR
- if (gContainerLib)
- {
- CARegisterFloatingWindow(fTearOffWindow->fWMgrWindow);
- FailOSErr(CAError());
- }
- #endif
-
- fTearOffWindow->Open(); // show the torn-off window
-
- fTearOffWindow->Select(); // select the torn-off window
- }
- } // TShowTearOffWindowCommand::DoIt
-
-
- //========================================================================================
- // CLASS TTearOffMenuViewTracker
- //========================================================================================
- #undef Inherited
- #define Inherited TTracker
-
- #pragma segment TearOffInit
- MA_DEFINE_CLASS_M1(TTearOffMenuViewTracker, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TTearOffMenuViewTracker::TTearOffMenuViewTracker: Empty constructor to satisfy the compiler.
- //----------------------------------------------------------------------------------------
- #pragma segment ConstructorRes
-
- TTearOffMenuViewTracker::TTearOffMenuViewTracker()
- {
- } // TTearOffMenuViewTracker::TTearOffMenuViewTracker
-
- //----------------------------------------------------------------------------------------
- // TTearOffMenuViewTracker destructor
- //----------------------------------------------------------------------------------------
- #pragma segment MADestructorRes
-
- TTearOffMenuViewTracker::~TTearOffMenuViewTracker()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // TTearOffMenuViewTracker::ITearOffMenuViewTracker:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffInit
-
- void TTearOffMenuViewTracker::ITearOffMenuViewTracker(CommandNumber itsCommandNumber,
- TCommandHandler* itsContext,
- Boolean canUndo,
- Boolean causesChange,
- TObject* objectToNotify,
- TView* itsView,
- TScroller* itsScroller,
- const VPoint& itsMouse)
- {
- this->ITracker(itsCommandNumber, itsContext, canUndo, causesChange, objectToNotify,
- itsView, itsScroller, itsMouse);
- } // TTearOffMenuViewTracker::ITearOffMenuViewTracker
-
- //----------------------------------------------------------------------------------------
- // TTearOffMenuViewTracker::IsReadyToPost:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffDoCommand
-
- Boolean TTearOffMenuViewTracker::IsReadyToPost() // override
- {
- ++(gDispatcher->fEventLevel);
- this->Process(); // perform this right away
- --(gDispatcher->fEventLevel);
- return FALSE;
- } // TTearOffMenuViewTracker::IsReadyToPost
-
-
- //========================================================================================
- // CLASS TTearOffTracker
- //========================================================================================
- #undef Inherited
- #define Inherited TTearOffMenuViewTracker
-
- #pragma segment TearOffInit
- MA_DEFINE_CLASS_M1(TTearOffTracker, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TTearOffTracker constructor
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffInit
-
- TTearOffTracker::TTearOffTracker()
- {
- fExitTracking = FALSE;
- fOrigin = gZeroPt;
- fTearOffMenu = NULL;
- fTearOffWindowOutline = NULL;
- } // TTearOffTracker::TTearOffTracker
-
- //----------------------------------------------------------------------------------------
- // TTearOffTracker::ITearOffTracker:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffInit
-
- void TTearOffTracker::ITearOffTracker(CPoint hitPt,
- TTearOffMenuView* tearOffMenu)
- {
- VPoint theMouse(hitPt);
- this->ITearOffMenuViewTracker(cNoCommand, NULL, kCantUndo, kDoesNotCauseChange, NULL,
- NULL, NULL, theMouse);
-
- fFreeOnCompletion = FALSE;
-
- fTearOffMenu = tearOffMenu;
-
- FailInfo fi;
- Try(fi)
- {
- fTearOffWindowOutline = MakeNewRgn();
-
- fi.Success();
- }
- else
- {
- this->Free();
- fi.ReSignal();
- }
- } // TTearOffTracker::ITearOffTracker
-
- //----------------------------------------------------------------------------------------
- // TTearOffTracker::Free:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffClose
-
- TTearOffTracker::~TTearOffTracker()
- {
- fTearOffWindowOutline = DisposeIfRgnHandle(fTearOffWindowOutline);
- } // TTearOffTracker::Free
-
- //----------------------------------------------------------------------------------------
- // TTearOffTracker::DoIt:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffDoCommand
-
- void TTearOffTracker::DoIt()
- {
- if (!fExitTracking) // ensure that we didn't exit the tracking loop
- {
- TWindow * aTearOffWindow = fTearOffMenu->fTearOffWindow;
-
- CPoint where = ((CRect &) (*fTearOffWindowOutline)->rgnBBox)[topLeft] + aTearOffWindow->fContentRegionInset;
-
- if (aTearOffWindow != NULL)
- {
- // NOTE: we can't just move and show the tear off window here because the menu
- // that we want to tearx off is currently displayed on the screen and the menu
- // manager has cached the bits underneath the currently displayed menu and we
- // might be moving our floating window into that territory thus invalidating
- // the menu manager's cache (which the menu manager will blit back in place
- // momentarily). To work-around this "feature" we'll simply post a command
- // which will do the work later. Isn't MacApp wonderful!
- TShowTearOffWindowCommand * aShowTearOffWindowCmd = new TShowTearOffWindowCommand;
- aShowTearOffWindowCmd->IShowTearOffWindowCommand(aTearOffWindow, where);
- fTearOffMenu->PostCommand(aShowTearOffWindowCmd);
- }
- }
- } // TTearOffTracker::DoIt
-
- //----------------------------------------------------------------------------------------
- // TTearOffTracker::TrackFeedback:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffDoCommand
-
- void TTearOffTracker::TrackFeedback(TrackPhase /* aTrackPhase */,
- const VPoint& /* anchorPoint */,
- const VPoint& /* previousPoint */,
- const VPoint& /* nextPoint */,
- Boolean mouseDidMove,
- Boolean /* turnItOn */)
- {
- if (mouseDidMove && !EmptyRgn(fTearOffWindowOutline))
- {
- PenPat(&qd.gray);
- FrameRgn(fTearOffWindowOutline); // draw/erase
- }
- } // TTearOffTracker::TrackFeedback
-
- //----------------------------------------------------------------------------------------
- // TTearOffTracker::TrackMouse:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffDoCommand
-
- TTracker* TTearOffTracker::TrackMouse(TrackPhase aTrackPhase,
- VPoint& ,
- VPoint& previousPoint,
- VPoint& nextPoint,
- Boolean)
- {
- TWindow * aTearOffWindow;
- short verticalOffset;
- short horizontalOffset;
- Boolean rgnsWereBuilt;
-
- CPoint qdPt = nextPoint.ToPoint();
- fExitTracking =!PtInRgn(qdPt, fTearOffMenu->fTearOffTrackingRegion);
-
- if (aTrackPhase == trackBegin)
- {
- aTearOffWindow = fTearOffMenu->fTearOffWindow;
- if (aTearOffWindow != NULL)
- {
- rgnsWereBuilt = aTearOffWindow->BuildWindowRegions(kBuild);
- GetWindowStructureRgn(aTearOffWindow->fWMgrWindow, fTearOffWindowOutline);
- aTearOffWindow->BuildWindowRegions(rgnsWereBuilt);
-
- // move the outline to the topleft of the window mgr graf port
- OffsetRgn(fTearOffWindowOutline, -(*fTearOffWindowOutline)->rgnBBox.left, -(*fTearOffWindowOutline)->rgnBBox.top);
-
- // move the outline so that it's centered at the mouse
- verticalOffset = (((CRect &) (*fTearOffWindowOutline)->rgnBBox).GetLength(vSel)) / 2;
- horizontalOffset = (((CRect &) (*fTearOffWindowOutline)->rgnBBox).GetLength(hSel)) / 2;
- OffsetRgn(fTearOffWindowOutline, (short)(previousPoint.h - horizontalOffset), (short)(previousPoint.v - verticalOffset));
- }
- //aTearOffWindow != NULL
- }
- else
- OffsetRgn(fTearOffWindowOutline, (short)(nextPoint.h - previousPoint.h), (short)(nextPoint.v - previousPoint.v));
- return this;
- } // TTearOffTracker::TrackMouse
-
- //----------------------------------------------------------------------------------------
- // TTearOffTracker::IsDoneTracking:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffDoCommand
-
- Boolean TTearOffTracker::IsDoneTracking()// override
- {
- return ((!StillDown()) || fExitTracking);
- } // TTearOffTracker::IsDoneTracking
-
-
- //========================================================================================
- // CLASS TTearOffMenuView
- //========================================================================================
- #undef Inherited
- #define Inherited TMenuView
-
- #pragma segment TearOffInit
- MA_DEFINE_CLASS_M1(TTearOffMenuView, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TTearOffMenuView constructor
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffInit
-
- TTearOffMenuView::TTearOffMenuView()
- {
- fTearOffTracker = NULL;
- fTearOffTrackingRegion = NULL;
- fTearOffWindow = NULL;
- } // TTearOffMenuView::TTearOffMenuView
-
- //----------------------------------------------------------------------------------------
- // TTearOffMenuView::ITearOffMenuView:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffInit
-
- void TTearOffMenuView::ITearOffMenuView(ResNumber rsrcID,
- short menuWidth,
- short menuHeight,
- TWindow* tearOffWindow)
- {
- this->IMenuView(rsrcID, menuWidth, menuHeight);
-
- FailInfo fi;
- Try(fi)
- {
- fTearOffTrackingRegion = MakeNewRgn();
- fTearOffWindow = tearOffWindow;
-
- this->InstallTearOffTracker();
- fi.Success();
- }
- else
- {
- this->Free();
- fi.ReSignal();
- }
- } // TTearOffMenuView::ITearOffMenuView
-
- //----------------------------------------------------------------------------------------
- // TTearOffMenuView::InstallTearOffTracker: For the sake of efficiency when tracking a
- // tear-off, we'll create the tear-off tracker and keep it with us, so we don't need to
- // allocate a new tracker every time we tear off a menu. If you want a different tracker
- // in your subclass of TTearOffMenuView, then override this method.
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffInit
-
- void TTearOffMenuView::InstallTearOffTracker()
- {
- TTearOffTracker * tearOffTracker;
-
- tearOffTracker = new TTearOffTracker;
- tearOffTracker->ITearOffTracker(gZeroPt, this);
- fTearOffTracker = tearOffTracker;
- } // TTearOffMenuView::InstallTearOffTracker
-
- //----------------------------------------------------------------------------------------
- // TTearOffMenuView::Free:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffClose
-
- TTearOffMenuView::~TTearOffMenuView()
- {
- fTearOffTracker = (TTearOffTracker *)FreeIfObject(fTearOffTracker);
- fTearOffTrackingRegion = DisposeIfRgnHandle(fTearOffTrackingRegion);
- } // TTearOffMenuView::Free
-
- //----------------------------------------------------------------------------------------
- // TTearOffMenuView::HandleChooseMessage:
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffRes
-
- void TTearOffMenuView::HandleChooseMessage(short,
- MenuRef,
- CRect& menuRect,
- CPoint hitPt,
- short& whichItem)// override
- {
- short newItem;
- CRect hitRect;
- Boolean oldObjectPerm;
- TToolboxEvent * event = NULL;
- EventRecord theEventRecord;
- Boolean saveTrackingInMenu;
-
- // so that trackers know that they're tracking in menus
- saveTrackingInMenu = gTrackingInMenu;
- gTrackingInMenu = TRUE;
-
- newItem = kNoMenuItem; // default return
-
- if (this->IsEnabled()) // menu enabled
- {
- // see if CPoint is within hit area
- CRect hitRect = GetQDExtent() + fBorder;
- if (hitRect.Contains(hitPt)) // in menu view (not border)
- {
- // NOTE: Either your subclass of TTearOffMenuView should override
- // DoMouseCommand or one of TTearOffMenuView's view's subview's should
- // override DoMouseCommand so that it creates and posts a TTracker. SubClasses
- // of TTearOffMenuViewTrackers will be tracked immediately because of the its
- // override of IsReadyToPost. So, when we're done with HandleMouseDown below,
- // we simply tell the menu manager that no menu item was selected, ie
- // newItem == kNoMenuItem.
-
- theEventRecord.what = mouseDown;
- theEventRecord.message = 0;
- theEventRecord.when = TickCount();
- theEventRecord.where = hitPt;
- theEventRecord.modifiers = 0;
-
- if (Button())
- theEventRecord.modifiers |= btnState;
-
- if (IsCommandKeyDown())
- theEventRecord.modifiers |= cmdKey;
-
- if (IsOptionKeyDown())
- theEventRecord.modifiers |= optionKey;
-
- oldObjectPerm = AllocateObjectsFromPerm(FALSE);
- event = new TToolboxEvent;
- AllocateObjectsFromPerm(oldObjectPerm);
- event->IToolboxEvent(NULL, theEventRecord);
- event->fClickCount = gDispatcher->fClickCount;
- event->fAffectsMenus = FALSE;
- this->HandleMouseDown(hitPt, event, gStdHysteresis);
- event = (TToolboxEvent *)FreeIfObject(event);
- }
- else
- { // determine if we should track a tear off image
- LocalToGlobal(hitPt);
- if (PtInRgn(hitPt, this->GetTearOffTrackingRegion(menuRect)))
- {
- fTearOffTracker->fInitialPt = hitPt;
- this->PostCommand(fTearOffTracker);
- }
- }
- }
- else
- this->UpdateHighlight(whichItem, newItem); // Update highlighting
-
- gTrackingInMenu = saveTrackingInMenu;
-
- // Tell MenuManager about new item
- whichItem = newItem;
- } // TTearOffMenuView::HandleChooseMessage
-
- //----------------------------------------------------------------------------------------
- // TTearOffMenuView::GetTearOffTrackingRegion: This function returns
- // fTearOffTrackingRegion
- //----------------------------------------------------------------------------------------
- #pragma segment TearOffRes
-
- RgnHandle TTearOffMenuView::GetTearOffTrackingRegion(const CRect& menuRect)
- {
- if (EmptyRgn(fTearOffTrackingRegion))
- {
- CRect rgnRect = menuRect;
-
- // calculate the tracking region for the tearoff image
- LocalToGlobal(rgnRect[topLeft]);
- LocalToGlobal(rgnRect[botRight]);
- rgnRect.Inset(CPoint(-kTearOffMargin, -kTearOffMargin));
-
- CTemporaryRegion tempRgn;
-
- RectRgn(tempRgn, rgnRect);
- DiffRgn(GetGrayRgn(), tempRgn, fTearOffTrackingRegion);
- InsetRgn(fTearOffTrackingRegion, 4, 4);
- }
- return fTearOffTrackingRegion;
- } // TTearOffMenuView::GetTearOffTrackingRegion
-
- //----------------------------------------------------------------------------------------
- // End of UTearOffMenuView.cp
-
- #pragma segment Inline
-